/**
 * 物料 - 主界面
 * 
 * @author PSI
 * @copyright 2015 - present
 * @license GPL v3
 */
PCL.define("PSI.SLN0001.Goods.MainForm", {
  extend: "PSI.AFX.Form.MainForm",

  config: {
    pAddCategory: null,
    pEditCategory: null,
    pDeleteCategory: null,
    pAddGoods: null,
    pEditGoods: null,
    pDeleteGoods: null,
    pImportGoods: null,
    pGoodsSI: null,
    pAddBOM: null,
    pEditBOM: null,
    pDeleteBOM: null,
    pPriceSystem: null,
    pExcel: null
  },

  /**
   * 初始化组件
   * 
   * @override
   */
  initComponent() {
    const me = this;

    PCL.apply(me, {
      items: [{
        tbar: me.getToolbarCmp(),
        id: me.buildId(me, "panelQueryCmp"),
        region: "north",
        border: 0,
        height: 95,
        header: false,
        collapsible: true,
        collapseMode: "mini",
        layout: {
          type: "table",
          columns: 5
        },
        bodyCls: "PSI-Query-Panel",
        items: me.getQueryCmp()
      }, {
        region: "center",
        layout: "border",
        ...PSI.Const.BODY_PADDING,
        border: 0,
        items: [{
          region: "center",
          xtype: "panel",
          layout: "border",
          border: 0,
          items: [{
            region: "center",
            layout: "fit",
            border: 0,
            items: [me.getMainGrid()]
          }, {
            region: "south",
            layout: "fit",
            height: 200,
            split: true,
            collapsible: true,
            collapseMode: "mini",
            header: false,
            xtype: "tabpanel",
            border: 0,
            bodyStyle: { borderWidth: 0 },
            items: [me.getSIGrid(),
            me.getGoodsBOMGrid(),
            me.getGoodsPriceGrid()]
          }]
        }, {
          id: "panelCategory",
          xtype: "panel",
          region: "west",
          layout: "fit",
          width: 430,
          split: true,
          collapsible: true,
          header: false,
          border: 0,
          items: [me.getCategoryGrid()]
        }]
      }]
    });

    me.callParent(arguments);

    me.queryTotalGoodsCount();

    me.editQueryCode = PCL.getCmp(me.buildId(me, "editQueryCode"));
    me.editQueryName = PCL.getCmp(me.buildId(me, "editQueryName"));
    me.editQuerySpec = PCL.getCmp(me.buildId(me, "editQuerySpec"));
    me.editQueryBarCode = PCL.getCmp(me.buildId(me, "editQueryBarCode"));
    me.editQueryBrand = PCL.getCmp(me.buildId(me, "editQueryBrand"));

    // AFX
    me.__editorList = [
      me.editQueryCode,
      me.editQueryName,
      me.editQuerySpec,
      me.editQueryBarCode,
      me.editQueryBrand,
    ];

    me._dfGoodsInfo = PCL.getCmp(me.buildId(me, "dfGoodsInfo"));

    me._keyMapMain = PCL.create("PCL.util.KeyMap", PCL.getBody(), [{
      key: "N",
      ctrl: false,
      shift: false,
      alt: true,
      fn() {
        if (PSI.Const.msgBoxShowing) {
          return;
        }

        // 判断权限
        if (me.getPAddGoods() != "1") {
          return;
        }

        me._onAddGoods.apply(me, []);
      },
      scope: me
    }, {
      key: "Q",
      ctrl: false,
      shift: false,
      alt: true,
      fn() {
        if (PSI.Const.msgBoxShowing) {
          return;
        }
        me.editQueryCode?.focus();
      },
      scope: me
    }, {
      key: "H",
      ctrl: false,
      shift: false,
      alt: true,
      fn() {
        if (PSI.Const.msgBoxShowing) {
          return;
        }

        const panel = PCL.getCmp(me.buildId(me, "panelQueryCmp"));
        if (panel.getCollapsed()) {
          panel.expand();
        } else {
          panel.collapse();
        };
      },
      scope: me
    },
    ]);

  },

  /**
   * @private
   */
  getToolbarCmp() {
    const me = this;

    let result = [];

    const menu = [];

    if (me.getPAddCategory() == "1") {
      menu.push({
        text: "新建物料分类",
        ...PSI.Const.BTN_STYLE,
        handler: me._onAddCategory,
        scope: me
      });
    }
    if (me.getPEditCategory() == "1") {
      menu.push({
        text: "编辑物料分类",
        ...PSI.Const.BTN_STYLE,
        handler: me._onEditCategory,
        scope: me
      });
    }
    if (me.getPDeleteCategory() == "1") {
      menu.push({
        text: "删除物料分类",
        ...PSI.Const.BTN_STYLE,
        handler: me._onDeleteCategory,
        scope: me
      });
    }
    if (menu.length > 0) {
      result.push({
        text: "物料分类",
        iconCls: "PSI-tb-new",
        ...PSI.Const.BTN_STYLE,
        menu
      });
    }

    if (result.length > 0) {
      result.push("-");
    }

    let flag = false;
    if (me.getPAddGoods() == "1") {
      flag = true;
      result.push({
        iconCls: "PSI-tb-new-entity",
        text: "新建物料 <span class='PSI-shortcut-DS'>Alt + N</span>",
        tooltip: me.buildTooltip("快捷键：Alt + N"),
        ...PSI.Const.BTN_STYLE,
        handler: me._onAddGoods,
        scope: me
      });
    }
    if (me.getPImportGoods() == "1") {
      flag = true;
      result.push({
        text: "导入物料",
        ...PSI.Const.BTN_STYLE,
        disabled: me.getPImportGoods() == "0",
        handler: me._onImportGoods,
        scope: me
      });
    }
    if (flag) {
      result.push("-");
    }
    flag = false;
    if (me.getPEditGoods() == "1") {
      flag = true;
      result.push({
        text: "编辑物料",
        ...PSI.Const.BTN_STYLE,
        handler: me._onEditGoods,
        scope: me
      });
    }
    if (me.getPDeleteGoods() == "1") {
      falg = true;
      result.push({
        text: "删除物料",
        ...PSI.Const.BTN_STYLE,
        disabled: me.getPDeleteGoods() == "0",
        handler: me._onDeleteGoods,
        scope: me
      });
    }
    if (flag) {
      result.push("-");
    }
    if (me.getPExcel() == "1") {
      result.push({
        text: "导出Excel",
        ...PSI.Const.BTN_STYLE,
        disabled: me.getPExcel() == "0",
        handler: me._onExcel,
        scope: me
      });
    }

    // 物料颜色
    if (PSI.Const.ENABLE_MATERIAL_COLOR == "1") {
      if (me.getPAddGoods() == "1") {
        // 有新建物料权限的时候，也允许根据物料颜色生成物料
        if (result.length > 0) {
          result.push("-");
        }
        const list = [];
        list.push({
          text: "根据物料颜色生成物料",
          scope: me,
          handler: me._onGenGoodsByMaterialColor,
          id: "buttonEdit"
        });

        result.push({
          text: "应用物料颜色",
          ...PSI.Const.BTN_STYLE,
          menu: list
        });
      }
    } // end of if (PSI.Const.ENABLE_MATERIAL_COLOR == "1")

    if (result.length > 0) {
      result.push("-", {
        iconCls: "PSI-tb-help",
        text: "指南",
        ...PSI.Const.BTN_STYLE,
        handler() {
          me.focus();
          window.open(me.URL("Home/Help/index?t=goods"));
        }
      }, "-", {
        iconCls: "PSI-tb-close",
        text: "关闭",
        ...PSI.Const.BTN_STYLE,
        handler() {
          me.focus();
          me.closeWindow();
        }
      }, {
        // 空容器，只是为了撑高工具栏
        xtype: "container", height: 28,
        items: []
      });
    }

    result = result.concat(me.getShortcutCmp());

    return result;
  },

  /**
   * 快捷访问
   * 
   * @private
   */
  getShortcutCmp() {
    return ["->",
      {
        cls: "PSI-Shortcut-Cmp",
        labelWidth: 0,
        emptyText: "快捷访问",
        xtype: "psi_mainmenushortcutfield",
        width: 90
      }
    ];
  },

  getQueryCmp() {
    const me = this;
    return [{
      xtype: "container",
      height: 26,
      html: `<h2 style='margin-left:20px;margin-top:18px;color:#595959;display:inline-block'>物料</h2>
              &nbsp;&nbsp;<span style='color:#8c8c8c'>主数据</span>
              <div style='float:right;display:inline-block;margin:10px 0px 0px 20px;border-left:1px solid #e5e6e8;height:40px'>&nbsp;</div>
              `
    }, {
      id: me.buildId(me, "editQueryCode"),
      labelWidth: 105,
      labelAlign: "right",
      labelSeparator: "",
      fieldLabel: "物料编码 <span class='PSI-shortcut-DS'>Alt + Q</span>",
      margin: "5, 0, 0, 0",
      width: 250,
      xtype: "textfield",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      }
    }, {
      id: me.buildId(me, "editQueryName"),
      labelWidth: 60,
      labelAlign: "right",
      labelSeparator: "",
      fieldLabel: "品名",
      margin: "5, 0, 0, 0",
      xtype: "textfield",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      }
    }, {
      id: me.buildId(me, "editQuerySpec"),
      labelWidth: 60,
      labelAlign: "right",
      labelSeparator: "",
      fieldLabel: "规格型号",
      margin: "5, 0, 0, 0",
      xtype: "textfield",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      }
    }, {
      xtype: "container",
      items: [{
        xtype: "button",
        text: "查询",
        cls: "PSI-Query-btn1",
        width: 100,
        height: 26,
        margin: "5, 0, 0, 20",
        handler: me._onQuery,
        scope: me
      }, {
        xtype: "button",
        text: "清空查询条件",
        cls: "PSI-Query-btn2",
        width: 100,
        height: 26,
        margin: "5, 0, 0, 5",
        handler: me._onClearQuery,
        scope: me
      }, {
        xtype: "button",
        text: "隐藏工具栏 <span class='PSI-shortcut-DS'>Alt + H</span>",
        cls: "PSI-Query-btn3",
        width: 140,
        height: 26,
        iconCls: "PSI-button-hide",
        margin: "5 0 0 20",
        handler() {
          PCL.getCmp(me.buildId(me, "panelQueryCmp")).collapse();
        },
        scope: me
      }]
    }, { xtype: "container" }, {
      id: me.buildId(me, "editQueryBarCode"),
      labelWidth: 65,
      labelAlign: "right",
      labelSeparator: "",
      fieldLabel: "条形码",
      margin: "5, 0, 0, 0",
      width: 250,
      xtype: "textfield",
      listeners: {
        specialkey: {
          fn: me.__onEditSpecialKey,
          scope: me
        }
      }
    }, {
      id: me.buildId(me, "editQueryBrand"),
      labelWidth: 60,
      labelAlign: "right",
      labelSeparator: "",
      fieldLabel: "品牌",
      margin: "5, 0, 0, 0",
      xtype: "PSI_goods_brand_field",
      showModal: true,
      listeners: {
        specialkey: {
          fn: me.__onLastEditSpecialKey,
          scope: me
        }
      }
    }];
  },

  /**
   * @private
   */
  getMainGrid() {
    const me = this;

    if (me._mainGrid) {
      return me._mainGrid;
    }

    const modelName = me.buildModelName(me, "PSIGoods");
    PCL.define(modelName, {
      extend: "PCL.data.Model",
      fields: ["id", "code", "name", "spec", "unitId",
        "unitName", "categoryId", "salePrice",
        "purchasePrice", "barCode", "memo", "dataOrg",
        "brandFullName", "recordStatus", "taxRate", "mType"]
    });

    const store = PCL.create("PCL.data.Store", {
      autoLoad: false,
      model: modelName,
      data: [],
      pageSize: 20,
      proxy: {
        type: "ajax",
        actionMethods: {
          read: "POST"
        },
        url: me.URL("SLN0001/Goods/goodsList"),
        reader: {
          root: 'goodsList',
          totalProperty: 'totalCount'
        }
      }
    });

    store.on("beforeload", () => {
      store.proxy.extraParams = me.getQueryParam();
    });
    store.on("load", (e, records, successful) => {
      if (successful) {
        me.refreshCategoryCount();
        me.gotoGoodsGridRecord(me._lastId);
      }
    });

    me._mainGrid = PCL.create("PCL.grid.Panel", {
      cls: "PSI-FC",
      viewConfig: {
        enableTextSelection: true
      },
      tbar: [" ", {
        xtype: "displayfield",
        id: me.buildId(me, "dfGoodsInfo"),
        value: "物料列表"
      }, "->", {
          id: "pagingToolbar",
          border: 0,
          xtype: "pagingtoolbar",
          store: store
        }, "-", {
          xtype: "displayfield",
          fieldStyle: "font-size:13px",
          value: "每页显示"
        }, {
          id: "comboCountPerPage",
          xtype: "combobox",
          editable: false,
          width: 60,
          store: PCL.create("PCL.data.ArrayStore", {
            fields: ["text"],
            data: [["20"], ["50"], ["100"], ["300"],
            ["1000"]]
          }),
          value: 20,
          listeners: {
            change: {
              fn() {
                store.pageSize = PCL.getCmp("comboCountPerPage").getValue();
                store.currentPage = 1;
                PCL.getCmp("pagingToolbar").doRefresh();
              },
              scope: me
            }
          }
        }, {
          xtype: "displayfield",
          fieldStyle: "font-size:13px",
          value: "条物料记录"
        }],
      columnLines: true,
      columns: [PCL.create("PCL.grid.RowNumberer", {
        text: "#",
        width: 40
      }), {
        header: "编码",
        dataIndex: "code",
        menuDisabled: true,
        sortable: false,
        renderer(value, metaData, record) {
          if (parseInt(record.get("recordStatus")) == 1000) {
            return value;
          } else {
            return `<span class="PSI-record-disabled">${value}</span>`;
          }
        }
      }, {
        header: "物料类型",
        dataIndex: "mType",
        menuDisabled: true,
        sortable: false,
        width: 70
      }, {
        header: "品名",
        dataIndex: "name",
        menuDisabled: true,
        sortable: false,
        width: 300,
        renderer(value, metaData, record) {
          if (parseInt(record.get("recordStatus")) == 1000) {
            return value;
          } else {
            return `<span class="PSI-record-disabled">${value}</span>`;
          }
        }
      }, {
        header: "规格型号",
        dataIndex: "spec",
        menuDisabled: true,
        sortable: false,
        width: 200
      }, {
        header: "计量单位",
        dataIndex: "unitName",
        menuDisabled: true,
        sortable: false,
        width: 80
      }, {
        header: "品牌",
        dataIndex: "brandFullName",
        menuDisabled: true,
        sortable: false
      }, {
        header: "销售基准价",
        dataIndex: "salePrice",
        menuDisabled: true,
        sortable: false,
        align: "right",
        xtype: "numbercolumn"
      }, {
        header: "建议采购价",
        dataIndex: "purchasePrice",
        menuDisabled: true,
        sortable: false,
        align: "right",
        xtype: "numbercolumn"
      }, {
        header: "税率",
        dataIndex: "taxRate",
        menuDisabled: true,
        sortable: false,
        align: "right"
      }, {
        header: "条形码",
        dataIndex: "barCode",
        menuDisabled: true,
        sortable: false
      }, {
        header: "备注",
        dataIndex: "memo",
        menuDisabled: true,
        sortable: false,
        width: 300
      }, {
        header: "数据域",
        dataIndex: "dataOrg",
        menuDisabled: true,
        sortable: false
      }, {
        header: "状态",
        dataIndex: "recordStatus",
        menuDisabled: true,
        sortable: false,
        renderer(value) {
          if (parseInt(value) == 1000) {
            return "启用";
          } else {
            return "<span style='color:red'>停用</span>";
          }
        }
      }],
      store: store,
      listeners: {
        itemdblclick: {
          fn: me._onEditGoods,
          scope: me
        },
        select: {
          fn: me._onGoodsSelect,
          scope: me
        }
      }
    });

    return me._mainGrid;
  },

  /**
   * 新建物料分类
   * @private
   */
  _onAddCategory() {
    const me = this;

    const form = PCL.create("PSI.SLN0001.Goods.CategoryEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me
    });

    form.show();
  },

  /**
   * 编辑物料分类
   * @private
   */
  _onEditCategory() {
    const me = this;

    const item = me.getCategoryGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要编辑的物料分类");
      return;
    }

    const category = item[0];

    const form = PCL.create("PSI.SLN0001.Goods.CategoryEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me,
      entity: category
    });

    form.show();
  },

  /**
   * 删除物料分类
   * @private
   */
  _onDeleteCategory() {
    const me = this;

    const item = me.getCategoryGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要删除的物料分类");
      return;
    }

    const category = item[0];

    const info = `请确认是否删除物料分类: <span style="color:red">${category.get("text")}</span>`;

    me.confirm(info, () => {
      const el = PCL.getBody();
      el.mask("正在删除中...");
      me.ajax({
        url: me.URL("SLN0001/Goods/deleteCategory"),
        params: {
          id: category.get("id")
        },
        callback(options, success, response) {
          el.unmask();

          if (success) {
            const data = me.decodeJSON(response.responseText);
            if (data.success) {
              me.tip("成功完成删除操作", true);
              me.freshCategoryGrid();
            } else {
              me.showInfo(data.msg);
            }
          } else {
            me.showInfo("网络错误");
          }
        }
      });
    });
  },

  /**
   * 刷新物料分类Grid
   */
  freshCategoryGrid(id) {
    const me = this;
    const store = me.getCategoryGrid().getStore();
    store.load();
  },

  /**
   * 刷新物料Grid
   */
  freshGoodsGrid() {
    const me = this;
    const item = me.getCategoryGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me._dfGoodsInfo.setValue("物料列表");
      return;
    }

    PCL.getCmp("pagingToolbar").doRefresh()
  },

  /**
   * @private
   */
  _onCategoryGridSelect() {
    const me = this;
    me.getSIGrid().setTitle("物料安全库存");
    me.getSIGrid().getStore().removeAll();
    me.getGoodsBOMGrid().getStore().removeAll();
    me.getGoodsPriceGrid().getStore().removeAll();

    me.getMainGrid().getStore().currentPage = 1;

    me.freshGoodsGrid();
  },

  /**
   * 新建物料
   * 
   * @private
   */
  _onAddGoods() {
    const me = this;

    if (me.getCategoryGrid().getStore().getCount() == 0) {
      me.showInfo("没有物料分类，请先新建物料分类");
      return;
    }

    const form = PCL.create("PSI.SLN0001.Goods.GoodsEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me
    });

    form.show();
  },

  /**
   * 编辑物料
   * 
   * @private
   */
  _onEditGoods() {
    const me = this;
    if (me.getPEditGoods() == "0") {
      return;
    }

    let item = me.getCategoryGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择物料分类");
      return;
    }

    const category = item[0];

    item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要编辑的物料");
      return;
    }

    const goods = item[0];
    goods.set("categoryId", category.get("id"));
    const form = PCL.create("PSI.SLN0001.Goods.GoodsEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me,
      entity: goods
    });

    form.show();
  },

  /**
   * 删除物料
   * 
   * @private
   */
  _onDeleteGoods() {
    const me = this;
    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要删除的物料");
      return;
    }

    const goods = item[0];

    const store = me.getMainGrid().getStore();
    let index = store.findExact("id", goods.get("id"));
    index--;
    const preItem = store.getAt(index);
    if (preItem) {
      me._lastId = preItem.get("id");
    }

    const info = `请确认是否删除物料: <span style='color:red'>${goods.get("name")} ${goods.get("spec")}</span>`;

    me.confirm(info, () => {
      const el = PCL.getBody();
      el.mask("正在删除中...");
      me.ajax({
        url: me.URL("SLN0001/Goods/deleteGoods"),
        params: {
          id: goods.get("id")
        },
        callback(options, success, response) {
          el.unmask();

          if (success) {
            const data = me.decodeJSON(response.responseText);
            if (data.success) {
              me.tip("成功完成删除操作", true);
              me.freshGoodsGrid();
            } else {
              me.showInfo(data.msg);
            }
          } else {
            me.showInfo("网络错误");
          }
        }

      });
    });
  },

  /**
   * TODO 需要清理代码
   * 
   * @private
   */
  gotoCategoryGridRecord(id) {
    const me = this;
    const grid = me.getCategoryGrid();
    const store = grid.getStore();
    if (id) {
      const r = store.findExact("id", id);
      if (r != -1) {
        grid.getSelectionModel().select(r);
      } else {
        grid.getSelectionModel().select(0);
      }
    }
  },

  /**
   * @private
   */
  gotoGoodsGridRecord(id) {
    const me = this;
    const grid = me.getMainGrid();
    const store = grid.getStore();
    if (id) {
      const r = store.findExact("id", id);
      if (r != -1) {
        grid.getSelectionModel().select(r);
        grid.getSelectionModel().setLastFocused(store.getAt(r));
      } else {
        grid.getSelectionModel().select(0);
      }
    }
  },

  /**
   * TODO 需要清理代码
   * @private
   */
  refreshCategoryCount() {
    const me = this;
    const item = me.getCategoryGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      return;
    }
  },

  /**
   * @private
   */
  getQueryParamForCategory() {
    const me = this;

    const result = {};

    if (!me.editQueryCode) {
      return result;
    }

    const code = me.editQueryCode.getValue();
    if (code) {
      result.code = code;
    }

    const name = me.editQueryName.getValue();
    if (name) {
      result.name = name;
    }

    const spec = me.editQuerySpec.getValue();
    if (spec) {
      result.spec = spec;
    }

    const barCode = me.editQueryBarCode.getValue();
    if (barCode) {
      result.barCode = barCode;
    }

    const brandId = me.editQueryBrand.getIdValue();
    if (brandId) {
      result.brandId = brandId;
    }

    return result;
  },

  /**
   * @private
   */
  getQueryParam() {
    const me = this;
    const item = me.getCategoryGrid().getSelectionModel().getSelection();
    let categoryId;
    if (item == null || item.length != 1) {
      categoryId = null;
    } else {
      categoryId = item[0].get("id");
    }

    const result = {
      categoryId
    };

    const code = me.editQueryCode.getValue();
    if (code) {
      result.code = code;
    }

    const name = me.editQueryName.getValue();
    if (name) {
      result.name = name;
    }

    const spec = me.editQuerySpec.getValue();
    if (spec) {
      result.spec = spec;
    }

    const barCode = me.editQueryBarCode.getValue();
    if (barCode) {
      result.barCode = barCode;
    }

    const brandId = me.editQueryBrand.getIdValue();
    if (brandId) {
      result.brandId = brandId;
    }

    return result;
  },

  /**
   * 查询
   * 
   * @private
   */
  _onQuery() {
    const me = this;

    me.getMainGrid().getStore().removeAll();
    me.getSIGrid().setTitle("物料安全库存");
    me.getSIGrid().getStore().removeAll();
    me.getGoodsBOMGrid().getStore().removeAll();
    me.getGoodsPriceGrid().getStore().removeAll();

    me.queryTotalGoodsCount();

    me.freshCategoryGrid();
  },

  /**
   * 清除查询条件
   * 
   * @private
   */
  _onClearQuery() {
    const me = this;

    me.editQueryCode.setValue("");
    me.editQueryName.setValue("");
    me.editQuerySpec.setValue("");
    me.editQueryBarCode.setValue("");

    me.editQueryBrand.clearIdValue();

    me._onQuery();
  },

  /**
   * 安全库存Grid
   */
  getSIGrid() {
    const me = this;
    if (me._siGrid) {
      return me._siGrid;
    }

    const modelName = me.buildModelName(me, "GoodsSafetyInventory");
    PCL.define(modelName, {
      extend: "PCL.data.Model",
      fields: ["id", "warehouseCode", "warehouseName",
        "safetyInventory", {
          name: "inventoryCount",
          type: "float"
        }, "unitName", "inventoryUpper"]
    });

    me._siGrid = PCL.create("PCL.grid.Panel", {
      cls: "PSI-HL",
      viewConfig: {
        enableTextSelection: true
      },
      features: [{
        ftype: "summary",
        dock: "bottom"
      }],
      title: "物料安全库存",
      tbar: [{
        iconCls: "PSI-tb-new-subentity",
        text: "设置物料安全库存",
        ...PSI.Const.BTN_STYLE,
        disabled: me.getPGoodsSI() == "0",
        handler: me._onSafetyInventory,
        scope: me
      }],
      columnLines: false,
      columns: [{
        header: "仓库编码",
        dataIndex: "warehouseCode",
        width: 80,
        menuDisabled: true,
        sortable: false
      }, {
        header: "仓库名称",
        dataIndex: "warehouseName",
        width: 100,
        menuDisabled: true,
        sortable: false
      }, {
        header: "库存上限",
        dataIndex: "inventoryUpper",
        width: 120,
        menuDisabled: true,
        sortable: false,
        align: "right",
        xtype: "numbercolumn",
        format: "0"
      }, {
        header: "安全库存量",
        dataIndex: "safetyInventory",
        width: 120,
        menuDisabled: true,
        sortable: false,
        align: "right",
        xtype: "numbercolumn",
        format: "0",
        summaryRenderer() {
          return "当前库存合计";
        }
      }, {
        header: "当前库存",
        dataIndex: "inventoryCount",
        width: 120,
        menuDisabled: true,
        sortable: false,
        align: "right",
        xtype: "numbercolumn",
        summaryType: "sum",
        format: "0"
      }, {
        header: "计量单位",
        dataIndex: "unitName",
        width: 80,
        menuDisabled: true,
        sortable: false
      }],
      store: PCL.create("PCL.data.Store", {
        model: modelName,
        autoLoad: false,
        data: []
      }),
      listeners: {
        itemdblclick: {
          fn: me._onSafetyInventory,
          scope: me
        }
      }
    });

    return me._siGrid;
  },

  /**
   * @private
   */
  _onGoodsSelect() {
    const me = this;
    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.getSIGrid().setTitle("物料安全库存");
      me.getGoodsBOMGrid().setTitle("BOM");
      return;
    }

    me.refreshGoodsSI();

    me.refreshGoodsBOM();

    me.refreshGoodsPriceSystem();
  },

  /**
   * @private
   */
  refreshGoodsSI() {
    const me = this;
    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      return;
    }

    const goods = item[0];
    const info = goods.get("code") + " " + goods.get("name") + " "
      + goods.get("spec");

    const grid = me.getSIGrid();
    grid.setTitle("物料[" + info + "]的安全库存");

    const el = grid.getEl() || PCL.getBody();
    el.mask(PSI.Const.LOADING);
    me.ajax({
      url: me.URL("SLN0001/Goods/goodsSafetyInventoryList"),
      params: {
        id: goods.get("id")
      },
      callback(options, success, response) {
        const store = grid.getStore();

        store.removeAll();

        if (success) {
          const data = me.decodeJSON(response.responseText);
          store.add(data);
        }

        el.unmask();
      }
    });
  },

  /**
   * @private
   */
  refreshGoodsBOM() {
    const me = this;
    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      return;
    }

    const goods = item[0];

    const gridBOM = me.getGoodsBOMGrid();
    const elBOM = gridBOM.getEl();
    if (elBOM) {
      elBOM.mask(PSI.Const.LOADING);
    }

    me.ajax({
      url: me.URL("SLN0001/Goods/goodsBOMList"),
      params: {
        id: goods.get("id")
      },
      callback(options, success, response) {
        const store = gridBOM.getStore();

        store.removeAll();

        if (success) {
          const data = me.decodeJSON(response.responseText);
          store.add(data);
        }

        if (elBOM) {
          elBOM.unmask();
        }
      }
    });
  },

  /**
   * 设置安全库存
   * 
   * @private
   */
  _onSafetyInventory() {
    const me = this;
    if (me.getPGoodsSI() == "0") {
      return;
    }

    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要设置安全库存的物料");
      return;
    }

    const goods = item[0];

    const form = PCL.create("PSI.SLN0001.Goods.SafetyInventoryEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me,
      entity: goods
    });

    form.show();
  },

  /**
   * 导入物料
   * 
   * @private
   */
  _onImportGoods() {
    const me = this;

    const form = PCL.create("PSI.SLN0001.Goods.GoodsImportForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me
    });

    form.show();
  },

  /**
   * 物料分类Grid
   * 
   * @private
   */
  getCategoryGrid() {
    const me = this;
    if (me._categoryGrid) {
      return me._categoryGrid;
    }

    const modelName = "PSIGoodsCategory";
    PCL.define(modelName, {
      extend: "PCL.data.Model",
      fields: ["id", "text", "fullName", "code", "cnt", "leaf",
        "children", "taxRate", "mType"]
    });

    const store = PCL.create("PCL.data.TreeStore", {
      model: modelName,
      proxy: {
        type: "ajax",
        actionMethods: {
          read: "POST"
        },
        url: me.URL("SLN0001/Goods/allCategories")
      },
      listeners: {
        beforeload: {
          fn() {
            store.proxy.extraParams = me.getQueryParamForCategory();
          },
          scope: me
        }
      }

    });

    store.on("load", me._onCategoryStoreLoad, me);

    me._categoryGrid = PCL.create("PCL.tree.Panel", {
      cls: "PSI",
      header: {
        height: 30,
        title: me.formatGridHeaderTitle("物料分类")
      },
      store: store,
      rootVisible: false,
      useArrows: true,
      viewConfig: {
        loadMask: true
      },
      tools: [{
        type: "close",
        handler() {
          PCL.getCmp("panelCategory").collapse();
        }
      }],
      bbar: [{
        id: "fieldTotalGoodsCount",
        xtype: "displayfield",
        value: "共有物料0种"
      }],
      columns: {
        defaults: {
          sortable: false,
          menuDisabled: true,
          draggable: false
        },
        items: [{
          xtype: "treecolumn",
          text: "分类",
          dataIndex: "text",
          width: 220
        }, {
          text: "编码",
          dataIndex: "code",
          width: 100
        }, {
          text: "物料种类数",
          dataIndex: "cnt",
          align: "right",
          width: 95,
          renderer(value) {
            return value == 0 ? "" : value;
          }
        }, {
          text: "默认税率",
          dataIndex: "taxRate",
          align: "center",
          width: 80
        }, {
          text: "物料类型",
          dataIndex: "mType",
          width: 150
        }]
      },
      listeners: {
        select: {
          fn(rowModel, record) {
            me._onCategoryTreeNodeSelect(record);
          },
          scope: me
        }
      }
    });

    return me._categoryGrid;
  },

  /**
   * @private
   */
  _onCategoryStoreLoad() {
    const me = this;
    const tree = me.getCategoryGrid();
    const root = tree.getRootNode();
    if (root) {
      const node = root.firstChild;
      if (node) {
        const m = tree.getSelectionModel();
        if (!m.hasSelection()) {
          m.select(node);
        }
      }
    }
  },

  /**
   * @private
   */
  _onCategoryTreeNodeSelect(record) {
    const me = this;

    if (!record) {
      me._dfGoodsInfo.setValue("物料列表");
      return;
    }

    const info = `<span class='PSI-title-keyword'>${record.get("fullName")}</span> - 物料列表`;
    me._dfGoodsInfo.setValue(info);

    me._onCategoryGridSelect();
  },

  queryTotalGoodsCount() {
    const me = this;
    me.ajax({
      url: me.URL("SLN0001/Goods/getTotalGoodsCount"),
      params: me.getQueryParamForCategory(),
      callback(options, success, response) {

        if (success) {
          const data = me.decodeJSON(response.responseText);
          PCL.getCmp("fieldTotalGoodsCount").setValue("共有物料"
            + data.cnt + "种");
        }
      }
    });
  },

  /**
   * 物料BOM Grid
   */
  getGoodsBOMGrid() {
    const me = this;
    if (me._bomGrid) {
      return me._bomGrid;
    }

    const modelName = me.buildModelName(me, "GoodsBOM");
    PCL.define(modelName, {
      extend: "PCL.data.Model",
      fields: ["id", "goodsId", "goodsCode", "goodsName",
        "goodsCount", "goodsSpec", "unitName",
        "costWeight", "costWeightNote"]
    });

    me._bomGrid = PCL.create("PCL.grid.Panel", {
      cls: "PSI-HL",
      viewConfig: {
        enableTextSelection: true
      },
      title: "静态BOM",
      tbar: [{
        iconCls: "PSI-tb-new-subentity",
        text: "新建子件",
        ...PSI.Const.BTN_STYLE,
        scope: me,
        disabled: me.getPAddBOM() == "0",
        handler: me._onAddBOM
      }, "-", {
        text: "编辑子件",
        ...PSI.Const.BTN_STYLE,
        scope: me,
        disabled: me.getPEditBOM() == "0",
        handler: me._onEditBOM
      }, "-", {
        text: "删除子件",
        ...PSI.Const.BTN_STYLE,
        scope: me,
        disabled: me.getPDeleteBOM() == "0",
        handler: me._onDeleteBOM
      }],
      columnLines: true,
      columns: {
        defaults: {
          menuDisabled: true,
          sortable: false
        },
        items: [{
          header: "子件编码",
          dataIndex: "goodsCode"
        }, {
          header: "子件名称",
          dataIndex: "goodsName",
          width: 300
        }, {
          header: "子件规格型号",
          dataIndex: "goodsSpec",
          width: 200
        }, {
          header: "子件数量",
          dataIndex: "goodsCount",
          width: 90,
          align: "right"
        }, {
          header: "子件单位",
          dataIndex: "unitName",
          width: 90
        }, {
          header: "成本分摊权重",
          dataIndex: "costWeight",
          width: 100,
          align: "right"
        }, {
          header: "成本分摊占比",
          dataIndex: "costWeightNote",
          width: 200
        }]
      },
      store: PCL.create("PCL.data.Store", {
        model: modelName,
        autoLoad: false,
        data: []
      })
    });

    return me._bomGrid;
  },

  /**
   * 新建子件
   * 
   * @private
   */
  _onAddBOM() {
    const me = this;

    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请先选择一个母件物料");
      return;
    }

    const goods = item[0];

    const form = PCL.create("PSI.SLN0001.Goods.GoodsBOMEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me,
      goods: goods
    });
    form.show();
  },

  /**
   * 编辑子件
   * 
   * @private
   */
  _onEditBOM() {
    const me = this;
    let item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请先选择一个母件物料");
      return;
    }

    const goods = item[0];

    item = me.getGoodsBOMGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要编辑的子件");
      return;
    }
    const subGoods = item[0];

    const form = PCL.create("PSI.SLN0001.Goods.GoodsBOMEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me,
      goods: goods,
      entity: subGoods
    });
    form.show();
  },

  /**
   * 删除子件
   * 
   * @private
   */
  _onDeleteBOM() {
    const me = this;

    let item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请先选择一个母件物料");
      return;
    }

    item = me.getGoodsBOMGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要删除的子件");
      return;
    }
    const subGoods = item[0];

    const info = `请确认是否删除子件: 
          <span style='color:red'>${subGoods.get("goodsName")}&nbsp;${subGoods.get("goodsSpec")}
          </span>?`;

    const confirmFunc = () => {
      const el = PCL.getBody();
      el.mask("正在删除中...");

      const r = {
        url: me.URL("SLN0001/Goods/deleteGoodsBOM"),
        params: {
          id: subGoods.get("id")
        },
        callback(options, success, response) {
          el.unmask();

          if (success) {
            const data = me.decodeJSON(response.responseText);
            if (data.success) {
              me.tip("成功完成删除操作", true);
              me.refreshGoodsBOM();
            } else {
              me.showInfo(data.msg);
            }
          } else {
            me.showInfo("网络错误");
          }
        }

      };
      me.ajax(r);
    };

    me.confirm(info, confirmFunc);
  },

  /**
   * 价格体系Grid
   * 
   * @private
   */
  getGoodsPriceGrid() {
    const me = this;
    if (me._priceGrid) {
      return me._priceGrid;
    }

    const modelName = me.buildModelName(me, "GoodsPriceSystem");
    PCL.define(modelName, {
      extend: "PCL.data.Model",
      fields: ["id", "name", "price"]
    });

    me._priceGrid = PCL.create("PCL.grid.Panel", {
      cls: "PSI-HL",
      viewConfig: {
        enableTextSelection: true
      },
      title: "价格体系",
      columnLines: true,
      columns: [{
        header: "名称",
        dataIndex: "name",
        width: 150,
        menuDisabled: true,
        sortable: false
      }, {
        header: "价格",
        dataIndex: "price",
        width: 100,
        menuDisabled: true,
        sortable: false,
        xtype: "numbercolumn",
        align: "right"
      }],
      store: PCL.create("PCL.data.Store", {
        model: modelName,
        autoLoad: false,
        data: []
      }),
      tbar: [{
        iconCls: "PSI-tb-new-subentity",
        text: "设置商品价格体系",
        ...PSI.Const.BTN_STYLE,
        disabled: me.getPPriceSystem() == "0",
        handler: me._onGoodsPriceSystem,
        scope: me
      }]
    });

    return me._priceGrid;
  },

  /**
   * @private
   */
  refreshGoodsPriceSystem() {
    const me = this;
    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      return;
    }

    const goods = item[0];

    const grid = me.getGoodsPriceGrid();
    const el = grid.getEl();
    if (el) {
      el.mask(PSI.Const.LOADING);
    }

    me.ajax({
      url: me.URL("SLN0001/Goods/goodsPriceSystemList"),
      params: {
        id: goods.get("id")
      },
      callback(options, success, response) {
        const store = grid.getStore();

        store.removeAll();

        if (success) {
          const data = me.decodeJSON(response.responseText);
          store.add(data);
        }

        if (el) {
          el.unmask();
        }
      }
    });
  },

  /**
   * 设置物料价格
   * 
   * @private
   */
  _onGoodsPriceSystem() {
    const me = this;

    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请选择要设置价格的商品");
      return;
    }

    const goods = item[0];

    // 只能给商品设置价格体系
    const mType = goods.get("mType");
    if (mType != "商品") {
      me.showInfo("只能给商品设置价格体系");
      return;
    }

    const form = PCL.create("PSI.SLN0001.Goods.GoodsPriceSystemEditForm", {
      renderTo: PSI.Const.RENDER_TO(),
      parentForm: me,
      entity: goods
    });

    form.show();
  },

  /**
   * 导出Excel
   * 
   * @private
   */
  _onExcel() {
    const me = this;

    me.confirm("请确认是否把物料资料导出为Excel文件？", () => {
      const url = "SLN0001/Goods/exportExcel";

      window.open(me.URL(url));
    });
  },

  /**
   * @private
   */
  _onGenGoodsByMaterialColor() {
    if (PSI.Const.ENABLE_MATERIAL_COLOR != "1") {
      return;
    }

    const me = this;

    const item = me.getMainGrid().getSelectionModel().getSelection();
    if (item == null || item.length != 1) {
      me.showInfo("请先选择一个物料");
      return;
    }

    const goods = item[0];
    me._lastId = goods.get("id");

    const info = `请确认是否以物料[编码:${goods.get("code")}，品名:${goods.get("name")}]为源物料，再根据物料颜色生成新的物料?`;

    me.confirm(info, () => {
      const el = PCL.getBody();
      el.mask("正在处理中...");
      me.ajax({
        url: me.URL("SLN0001/Goods/genGoodsByMaterialColor"),
        params: {
          id: goods.get("id")
        },
        callback(options, success, response) {
          el.unmask();

          if (success) {
            const data = me.decodeJSON(response.responseText);
            if (data.success) {
              me.tip("成功完成操作", true);
              me.freshGoodsGrid();
            } else {
              me.showInfo(data.msg);
            }
          } else {
            me.showInfo("网络错误");
          }
        }
      });
    });
  }
});
